<html>
<head><meta charset="utf-8"><title>Convert Result&lt;T, E&gt; to Result&lt;T, Box&lt;dyn Error&gt;&gt; · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Convert.20Result.3CT.2C.20E.3E.20to.20Result.3CT.2C.20Box.3Cdyn.20Error.3E.3E.html">Convert Result&lt;T, E&gt; to Result&lt;T, Box&lt;dyn Error&gt;&gt;</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="237462075"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Convert%20Result%3CT%2C%20E%3E%20to%20Result%3CT%2C%20Box%3Cdyn%20Error%3E%3E/near/237462075" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yizhe <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Convert.20Result.3CT.2C.20E.3E.20to.20Result.3CT.2C.20Box.3Cdyn.20Error.3E.3E.html#237462075">(May 05 2021 at 08:55)</a>:</h4>
<p>I'm trying to convert <code>Result&lt;T, E&gt;</code> to <code>Result&lt;T, Box&lt;dyn Error&gt;&gt;</code> so that I can handle different types of errors using the <code>?</code> syntax. Here's my first attempt, which doesn't compile:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">dyn_err</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">&gt;</span><span class="p">(</span><span class="n">result</span>: <span class="nb">Result</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Result</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="nb">Box</span><span class="o">&lt;</span><span class="k">dyn</span><span class="w"> </span><span class="n">Error</span><span class="o">&gt;&gt;</span><span class="w"></span>
<span class="w">    </span><span class="k">where</span><span class="w"> </span><span class="n">E</span>: <span class="nc">Error</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="o">'</span><span class="nb">static</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">result</span><span class="p">.</span><span class="n">map_err</span><span class="p">(</span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="nb">Box</span>::<span class="n">new</span><span class="p">(</span><span class="n">e</span><span class="p">))</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>The compiler complains <code>expected trait object dyn std::error::Error, found type parameter E</code>.</p>
<p>Confusingly, explicit pattern matching works as expected:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">dyn_err</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">&gt;</span><span class="p">(</span><span class="n">result</span>: <span class="nb">Result</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Result</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="nb">Box</span><span class="o">&lt;</span><span class="k">dyn</span><span class="w"> </span><span class="n">Error</span><span class="o">&gt;&gt;</span><span class="w"></span>
<span class="w">    </span><span class="k">where</span><span class="w"> </span><span class="n">E</span>: <span class="nc">Error</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="o">'</span><span class="nb">static</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">result</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="nb">Ok</span><span class="p">(</span><span class="n">t</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="n">t</span><span class="p">),</span><span class="w"></span>
<span class="w">        </span><span class="nb">Err</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="nb">Box</span>::<span class="n">new</span><span class="p">(</span><span class="n">e</span><span class="p">)),</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>What's the problem then?</p>



<a name="237471451"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Convert%20Result%3CT%2C%20E%3E%20to%20Result%3CT%2C%20Box%3Cdyn%20Error%3E%3E/near/237471451" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Frank Steffahn <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Convert.20Result.3CT.2C.20E.3E.20to.20Result.3CT.2C.20Box.3Cdyn.20Error.3E.3E.html#237471451">(May 05 2021 at 10:19)</a>:</h4>
<p>The problem is that <code>Box::new(e)</code> is of type <code>Box&lt;E&gt;</code> and you want <code>Box&lt;dyn Error&gt;</code>. This is a conversion that can happen implicitly due to <a href="https://doc.rust-lang.org/stable/reference/type-coercions.html#type-coercions">coercion</a>, but when it can happen is a bit dependent on type inference (in ways I admittedly don’t fully understand myself). The gist is: if type inference thinks early on that leaving it be a <code>Box&lt;E&gt;</code> is <em>fine</em>, especially around generics, such as <code>map_err</code> in this case, then it won’t come back and consider inserting a coercion.</p>
<p>It can be helped, the easiest way is probably by suggesting a coercion at the right place a bit more explicitly with <code>as _</code> like this</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">dyn_err</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">&gt;</span><span class="p">(</span><span class="n">result</span>: <span class="nb">Result</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Result</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="nb">Box</span><span class="o">&lt;</span><span class="k">dyn</span><span class="w"> </span><span class="n">Error</span><span class="o">&gt;&gt;</span><span class="w"></span>
<span class="w">    </span><span class="k">where</span><span class="w"> </span><span class="n">E</span>: <span class="nc">Error</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="o">'</span><span class="nb">static</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">result</span><span class="p">.</span><span class="n">map_err</span><span class="p">(</span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="nb">Box</span>::<span class="n">new</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="n">_</span><span class="p">)</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>in which case the compiler can fill in the details for the <code>_</code>. You can do so explicitly, too, of course:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">dyn_err</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">&gt;</span><span class="p">(</span><span class="n">result</span>: <span class="nb">Result</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Result</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="nb">Box</span><span class="o">&lt;</span><span class="k">dyn</span><span class="w"> </span><span class="n">Error</span><span class="o">&gt;&gt;</span><span class="w"></span>
<span class="w">    </span><span class="k">where</span><span class="w"> </span><span class="n">E</span>: <span class="nc">Error</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="o">'</span><span class="nb">static</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">result</span><span class="p">.</span><span class="n">map_err</span><span class="p">(</span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="nb">Box</span>::<span class="n">new</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nb">Box</span><span class="o">&lt;</span><span class="k">dyn</span><span class="w"> </span><span class="n">Error</span><span class="o">&gt;</span><span class="p">)</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>Furthermore for the <code>(E: Error) ⟶ Box&lt;dyn Error&gt;</code> conversion, there’s a <code>From</code> conversion so that this works:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">dyn_err</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">&gt;</span><span class="p">(</span><span class="n">result</span>: <span class="nb">Result</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Result</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="nb">Box</span><span class="o">&lt;</span><span class="k">dyn</span><span class="w"> </span><span class="n">Error</span><span class="o">&gt;&gt;</span><span class="w"></span>
<span class="w">    </span><span class="k">where</span><span class="w"> </span><span class="n">E</span>: <span class="nc">Error</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="o">'</span><span class="nb">static</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">result</span><span class="p">.</span><span class="n">map_err</span><span class="p">(</span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="n">e</span><span class="p">.</span><span class="n">into</span><span class="p">())</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>or like this</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">dyn_err</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">&gt;</span><span class="p">(</span><span class="n">result</span>: <span class="nb">Result</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Result</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="nb">Box</span><span class="o">&lt;</span><span class="k">dyn</span><span class="w"> </span><span class="n">Error</span><span class="o">&gt;&gt;</span><span class="w"></span>
<span class="w">    </span><span class="k">where</span><span class="w"> </span><span class="n">E</span>: <span class="nc">Error</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="o">'</span><span class="nb">static</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">result</span><span class="p">.</span><span class="n">map_err</span><span class="p">(</span><span class="nb">From</span>::<span class="n">from</span><span class="p">)</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>Finally, the <em>reason</em> for having this conversion is so that the <code>?</code> operator can do the <code>E -&gt; Box&lt;dyn Error&gt;</code> conversion, so that’s another solution</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">dyn_err</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">&gt;</span><span class="p">(</span><span class="n">result</span>: <span class="nb">Result</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Result</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="nb">Box</span><span class="o">&lt;</span><span class="k">dyn</span><span class="w"> </span><span class="n">Error</span><span class="o">&gt;&gt;</span><span class="w"></span>
<span class="w">    </span><span class="k">where</span><span class="w"> </span><span class="n">E</span>: <span class="nc">Error</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="o">'</span><span class="nb">static</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="nb">Ok</span><span class="p">(</span><span class="n">result</span><span class="o">?</span><span class="p">)</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>